home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / nroff~06.zoo / hyph.c < prev    next >
C/C++ Source or Header  |  1992-07-17  |  38KB  |  1,664 lines

  1. static char *rcsid_hyph_c="$Id: hyph.c,v 1.2 1992/07/16 21:42:50 rosenkra Exp $";
  2.  
  3. /*
  4.  * $Log: hyph.c,v $
  5.  * Revision 1.2  1992/07/16  21:42:50  rosenkra
  6.  * new at this rev. ported to gcc.
  7.  *
  8.  */
  9.  
  10. #undef DEBUG_HYPHEN
  11. #undef STANDALONE
  12.  
  13. #ifdef STANDALONE
  14. # ifndef DEBUG_HYPHEN
  15. #  define DEBUG_HYPHEN
  16. # endif
  17. #endif
  18.  
  19. /*
  20.  *    hyph - An implementation of the Knuth hyphenation algorithm, modified
  21.  *
  22.  *    currently, hyphen ret 0 if cannot be hyphenated, 1 for it was (or is)
  23.  *    soft hyphenated. should modify so that ret -1 if soft hyphenated or
  24.  *    n (positive) where n is index into string where there is a hard hyphen.
  25.  *    either that or check for a hard hyphen before even calling this routine
  26.  *
  27.  *    two entry points here:
  28.  *
  29.  *    char *do_hyphen (char *, int, char **, char **);
  30.  *    int hyphen (char *, char *);
  31.  */
  32.  
  33. #include <stdio.h>
  34. #include <ctype.h>
  35.  
  36. #ifdef ALCYON
  37. # ifndef void
  38. #  define void        int
  39. # endif
  40. #endif
  41.  
  42. /*
  43.  *    #defines for non-printing ASCII characters
  44.  */
  45. #define    NUL        0x00    /* ^@    */
  46. #define    SOH        0x01    /* ^A    */
  47. #define    STX        0x02    /* ^B    */
  48. #define    ETX        0x03    /* ^C    */
  49. #define    EOT        0x04    /* ^D    */
  50. #define    ENQ        0x05    /* ^E    */
  51. #define    ACK        0x06    /* ^F    */
  52. #define    BEL        0x07    /* ^G    */
  53. #define    BS        0x08    /* ^H    */
  54. #define    HT        0x09    /* ^I    */
  55. #define    LF        0x0a    /* ^J    */
  56. #define NL        LF
  57. #define    VT        0x0b    /* ^K    */
  58. #define    FF        0x0c    /* ^L    */
  59. #define    CR        0x0d    /* ^M    */
  60. #define    SO        0x0e    /* ^N    */
  61. #define    SI        0x0f    /* ^O    */
  62. #define    DLE        0x10    /* ^P    */
  63. #define    DC1        0x11    /* ^Q    */
  64. #define    DC2        0x12    /* ^R    */
  65. #define    DC3        0x13    /* ^S    */
  66. #define    DC4        0x14    /* ^T    */
  67. #define    NAK        0x15    /* ^U    */
  68. #define    SYN        0x16    /* ^V    */
  69. #define    ETB        0x17    /* ^W    */
  70. #define    CAN        0x18    /* ^X    */
  71. #define    EM        0x19    /* ^Y    */
  72. #define    SUB        0x1a    /* ^Z    */
  73. #define CPMEOF        SUB
  74. #define    ESC        0x1b    /* ^[    */
  75. #define    FS        0x1c    /* ^\    */
  76. #define    GS        0x1d    /* ^]    */
  77. #define    RS        0x1e    /* ^^    */
  78. #define    US        0x1f    /* ^_    */
  79. #define    DEL        0x7f    /* DEL    */
  80.  
  81.  
  82.  
  83.  
  84.  
  85. /*
  86.  *    if THING is #defined then words like "anything" will be split
  87.  *    any-thing. On the other hand, if it's defined the bathing is
  88.  *    split ba-thing. You can't have every-thing. In the present
  89.  *    version most of the -thing words are in the exception list.
  90.  *
  91.  * #define THING
  92.  */
  93.  
  94. /*
  95.  *    Various psuedo-subroutines. HYPHEN defines a bit to set when a hyphen
  96.  *    is inserted. HYPHENATE sets the bit, UNHYPHENATE clears it,
  97.  *    HAS_HYPHEN tests for it. The ER macro checks for an "er" at the end
  98.  *    of a word, it's used by the consonant pair checking routine.
  99.  *    Is consonant returns true if c is a consonant.
  100.  *
  101.  *    Note that a letter is marked if a hyphen can be inserted in front
  102.  *    of it.
  103.  */
  104. #define HYPHEN        0x80             /* soft hyphen bit */
  105. #define HYPHENATE(c)    ((c) |=  HYPHEN )    /* mark char */
  106. #define UNHYPHENATE(c)    ((c) &= ~HYPHEN )    /* unmark char */
  107. #define HAS_HYPHEN(c)    ((c) &   HYPHEN )    /* is it marked? */
  108.  
  109. #define ER(p,end)    ((*p & 0x7f)=='e' && (*(p+1) & 0x7f)=='r' && (p+1)==end)
  110.  
  111. #define isvowel(c)    (islower((c) & 0x7f)  &&  vt[((c) & 0x7f) - 'a'])
  112. #define isconsonant(c)    ((c) && !isvowel(c))
  113.  
  114.  
  115. /*    The dipthongs ch, gh, ph, sh and th are treated as single
  116.  *    consonants. The subroutine nextch() will map these two
  117.  *    characters into a single character as follows:
  118.  */
  119. #define CH        ('z'+1)        /* {     0x7b  \173    */
  120. #define GH        ('z'+2)        /* |     0x7c  \174    */
  121. #define PH        ('z'+3)        /* }     0x7d  \175    */
  122. #define SH        ('z'+4)        /* ~     0x7e  \176    */
  123. #define TH        ('z'+5)        /* DEL     0x7f  \177    */
  124.  
  125.  
  126. /*
  127.  *    global variables
  128.  */
  129. #ifdef DEBUG_HYPHEN
  130. static int      HyDebug = 0;    /* True if debug diagnostics are to be printed*/
  131. static void    bprint ();
  132. #endif
  133. static char          **States;    /* Ptr to table for current state machine*/
  134. static char        vt[] =
  135.             { 1,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0 };
  136.                /* a b c d e f g h i j k l m n o p q r s t u v w x y z */
  137.  
  138. /*
  139.  *    functions
  140.  */
  141. char           *do_hyphen ();    /* global entries */
  142.  
  143. int        hyphen ();
  144.  
  145. static char    *suffix ();
  146. static char    *prefix ();
  147. static char    nextch ();
  148. static int    isweird ();
  149. static void    consonants ();    /* these are all local (static)... */
  150. static void    phyphen ();
  151. static int    next ();
  152. static int    exception ();
  153. static int    wcmp ();
  154. static char    *bsearch ();
  155.  
  156. #ifdef __GNUC__
  157. #include <string.h>
  158. #else
  159. extern char    *index ();    /* these are external... */
  160. #endif
  161.  
  162.  
  163. #define MAXWLEN        132
  164.  
  165.  
  166.  
  167.  
  168. /*------------------------------*/
  169. /*    do_hyphen        */
  170. /*------------------------------*/
  171. char *do_hyphen (ps, n, p1, p2)
  172. register char  *ps;        /* word to hyphenate */
  173. int        n;        /* max number of chars before hyphen */
  174.                 /* if < 0, hyphenate anyway */
  175.                 /* if -1, hyphenate first avail location */
  176.                 /* if -2, hyphenate last avail location */
  177.                 /* if -3, hyphenate all locations */
  178. char          **p1;        /* -> first part up to and including hyphen */
  179. char          **p2;        /* -> last part after hyphen */
  180. {
  181.  
  182. /*
  183.  *    main entry point. space is allocated here so caller MUST use returned
  184.  *    pointer before next call. ptr to hyphenated word is returned or NULL
  185.  *    if it can't be hyphenated. word must be null terminated. max word len
  186.  *    allowed is MAXWLEN.
  187.  *
  188.  *    use:
  189.  *
  190.  *    char *p1, *p2, *ps;
  191.  *
  192.  *    if (ps = do_hyphen ("hyphenate", 4, &p1, &p2))
  193.  *    {
  194.  *        deal with hyphen:
  195.  *
  196.  *        ps -> "hy-phenate"
  197.  *        p1 -> "hy-..."
  198.  *        p2 -> "phenate"
  199.  *    }
  200.  */
  201.  
  202.     static char        buf[MAXWLEN+2];        /* result */
  203.     char            ibuf[MAXWLEN+2];    /* work space */
  204.     register char           *ebuf;            /* -> end of word */
  205.     register char           *p;
  206.     register char           *pb;
  207.     register int        cnt;
  208.  
  209.  
  210.  
  211.     /*
  212.      *   too short? too long?
  213.      */
  214.     if (strlen (ps) < 4 || strlen (ps) > MAXWLEN)
  215.         return ((char *) 0);
  216.  
  217.  
  218.  
  219.     /*
  220.      *   copy word to input buffer
  221.      */
  222.     for (ebuf = ibuf; *ps; ps++, ebuf++)
  223.         *ebuf = *ps & 0x7f;
  224.     *ebuf = '\0';
  225.  
  226.  
  227.  
  228.     /*
  229.      *   check for hard hyphen
  230.      */
  231.     for (p = ibuf; *p; p++)
  232.     {
  233.         if (*p == '-')
  234.         {
  235.             if (n >= 0)
  236.             {
  237.                 if (p - ibuf + 1 > n)
  238.                     return ((char *) 0);
  239.             }
  240.             strcpy (buf, ibuf);
  241.             *p1 = buf;
  242.             *p2 = (char *) (buf + (p - ibuf + 1));
  243.             return (buf);
  244.         }
  245.     }
  246.  
  247.  
  248.  
  249.     /*
  250.      *   do it. check if it worked. if not, return null
  251.      */
  252.     ebuf--;        /* -> last char */
  253.     if (hyphen (ibuf, ebuf))
  254.     {
  255.         if (n >= 0)
  256.         {
  257.             /*
  258.              *   n was given. check if hyphen fits length
  259.              *   needed...
  260.              */
  261.             for (cnt = 1, p = ibuf, pb = buf; *p && p <= ebuf;
  262.             p++, pb++, cnt++)
  263.             {
  264.                 if (HAS_HYPHEN(*p))
  265.                 {
  266.                     if (cnt > n)
  267.                         return ((char *) 0);
  268.                     else
  269.                     {
  270.                         *pb++ = '-';
  271.                         *p1 = buf;
  272.                         *p2 = pb;
  273.                         while (*p)
  274.                             *pb++ = *p++ & 0x7f;
  275.                         *pb = '\0';
  276.                         return (buf);
  277.                     }
  278.                 }
  279.                 *pb = *p & 0x7f;
  280.                 *(pb + 1) = '\0';
  281.             }
  282.             return ((char *) 0);
  283.         }
  284.         else if (n == -1)
  285.         {
  286.             /*
  287.              *   -1 was given. hyphenate first avail location
  288.              */
  289.             for (p = ibuf, pb = buf; *p && p <= ebuf; p++, pb++)
  290.             {
  291.                 if (HAS_HYPHEN(*p))
  292.                 {
  293.                     *pb++ = '-';
  294.                     *p1 = buf;
  295.                     *p2 = pb;
  296.                     while (*p)
  297.                         *pb++ = *p++ & 0x7f;
  298.                     *pb = '\0';
  299.                     return (buf);
  300.                 }
  301.                 *pb = *p & 0x7f;
  302.                 *(pb + 1) = '\0';
  303.             }
  304.             return ((char *) 0);
  305.         }
  306.         else if (n == -2)
  307.         {
  308.             /*
  309.              *   -2 was given. hyphenate last avail location
  310.              */
  311.             pb = &buf[MAXWLEN];
  312.             *pb = '\0';
  313.             for (p = &ibuf[strlen(ibuf)-1], pb--;
  314.             p >= ibuf; p--, pb--)
  315.             {
  316.                 if (HAS_HYPHEN(*p))
  317.                 {
  318.                     *p1 = buf;
  319.                     *p2 = pb;
  320.                     *pb-- = '-';
  321.                     while (p >= ibuf)
  322.                         *pb-- = *p-- & 0x7f;
  323.                     pb++;
  324.                     return (pb);
  325.                 }
  326.                 *pb = *p & 0x7f;
  327.                 *(pb + 1) = '\0';
  328.             }
  329.             return (buf);
  330.         }
  331.         else if (n == -3)
  332.         {
  333.             /*
  334.              *   -3 was given. hyphenate all locations
  335.              */
  336.             for (p = ibuf, pb = buf; *p && p <= ebuf; p++, pb++)
  337.             {
  338.                 if (HAS_HYPHEN(*p))
  339.                 {
  340.                     *pb++ = '-';
  341.                     *p1 = buf;
  342.                     *p2 = pb;
  343.                 }
  344.                 *pb = *p & 0x7f;
  345.                 *(pb + 1) = '\0';
  346.             }
  347.             *pb = '\0';
  348.             return (buf);
  349.         }
  350.         else
  351.             return ((char *) 0);    /* error in n */
  352.     }
  353.  
  354.     return ((char *) 0);
  355. }
  356.  
  357.  
  358.  
  359.  
  360. /*------------------------------*/
  361. /*    hyphen            */
  362. /*------------------------------*/
  363. int hyph